package com.hskn.hss.module.tloilcostcfg.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hskn.hss.core.annotation.DataScope;
import com.hskn.hss.core.domain.BaseEntity;
import com.hskn.hss.core.utils.LoginUtils;
import com.hskn.hss.entity.AjaxResult;
import com.hskn.hss.exception.ExcelReaderDataException;
import com.hskn.hss.exception.HssException;
import com.hskn.hss.module.costdictitem.entity.CostDictItem;
import com.hskn.hss.module.costdictitem.mapper.CostDictItemMapper;
import com.hskn.hss.module.costdictitem.service.ICostDictItemService;
import com.hskn.hss.module.depart.entity.SysDepart;
import com.hskn.hss.module.depart.mapper.SysDepartMapper;
import com.hskn.hss.module.depart.service.ISysDepartService;
import com.hskn.hss.module.statistics.vo.TlOilcostCfgRes;
import com.hskn.hss.module.tlcar.entity.TlCar;
import com.hskn.hss.module.tlcar.mapper.TlCarMapper;
import com.hskn.hss.module.tlcar.service.ITlCarService;
import com.hskn.hss.module.tlcartype.entity.TlCarType;
import com.hskn.hss.module.tlcartype.service.ITlCarTypeService;
import com.hskn.hss.module.tloilcostcfg.entity.TlOilcostCfg;
import com.hskn.hss.module.tloilcostcfg.mapper.TlOilcostCfgMapper;
import com.hskn.hss.module.tloilcostcfg.service.ITlOilcostCfgService;
import com.hskn.hss.module.tloilcostcfg.to.TlOilcostCfgListTO;
import com.hskn.hss.module.tloilcostcfg.vo.TlOilcostCfgExecelVO;
import com.hskn.hss.module.user.entity.User;
import com.hskn.hss.module.user.mapper.UserMapper;
import com.hskn.hss.module.user.service.IUserService;
import com.hskn.hss.module.userdepart.entity.SysUserDepart;
import com.hskn.hss.module.userdepart.mapper.SysUserDepartMapper;
import com.hskn.hss.to.ForIdsTO;
import com.hskn.hss.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author hskn
 * @since 2021-05-05
 */
@Service
public class TlOilcostCfgServiceImpl extends ServiceImpl<TlOilcostCfgMapper, TlOilcostCfg> implements ITlOilcostCfgService {
    @Resource
    TlOilcostCfgMapper TlOilcostCfgMapper;
    @Resource
    SysUserDepartMapper sysUserDepartMapper;
    @Resource
    ITlCarService carService;
    @Resource
    ITlCarTypeService carTypeService;
    @Resource
    CostDictItemMapper costDictItemMapper;
    @Resource
    ISysDepartService departService;
    @Resource
    IUserService userService;
    @Resource
    UserMapper userMapper;
    @Resource
    private SysDepartMapper departMapper;
    @Resource
    private TlCarMapper carMapper;
    @Autowired
    private ICostDictItemService costDictItemService;

    @Override
    public AjaxResult insert(JSONObject params) {

        String uid = LoginUtils.getUser().getUid();
        TlOilcostCfg tlOilcostCfg = params.getObject("data", TlOilcostCfg.class);
        QueryWrapper<SysUserDepart> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysUserDepart::getUserid, uid);
        String deptid = sysUserDepartMapper.selectOne(queryWrapper).getDepid();

        tlOilcostCfg.setId(StringUtils.uuid());
        tlOilcostCfg.setCreatby(uid);
        tlOilcostCfg.setCreattime(new Date());
        tlOilcostCfg.setDeptid(deptid);
        TlCar car = null;
        if (tlOilcostCfg != null) {
            car = carService.getById(tlOilcostCfg.getCarnumid());
            tlOilcostCfg.setCartype(car.getCartypeid());
            tlOilcostCfg.setDrivernameid(car.getDriverid());
            tlOilcostCfg.setDeptidforcar(car.getCardeptid());
        }
        int i = TlOilcostCfgMapper.insert(tlOilcostCfg);
        boolean flag = i > 0;

        if (flag) {
            return AjaxResult.success("操作成功");
        } else {
            return AjaxResult.fail("操作失败，请稍后再试");
        }
    }

    @Override
    public AjaxResult update(JSONObject params) {

        String uid = LoginUtils.getUser().getUid();
        TlOilcostCfg tlOilcostCfg = params.getObject("data", TlOilcostCfg.class);
        tlOilcostCfg.setUpdateby(uid);
        tlOilcostCfg.setUpdatetime(new Date());
        TlCar car = null;
        if (tlOilcostCfg != null) {
            car = carService.getById(tlOilcostCfg.getCarnumid());
            tlOilcostCfg.setCartype(car.getCartypeid());
            tlOilcostCfg.setDrivernameid(car.getDriverid());
            tlOilcostCfg.setDeptidforcar(car.getCardeptid());
        }
        int i = TlOilcostCfgMapper.updateById(tlOilcostCfg);

        boolean flag = i > 0;

        if (flag) {
            return AjaxResult.success("操作成功");
        } else {
            return AjaxResult.fail("操作失败，请稍后再试");
        }
    }

    @Override
    public AjaxResult deleteByid(ForIdsTO forIdsTO) {
        try {
            TlOilcostCfgMapper.deleteBatchIds(forIdsTO.getIds());
            return AjaxResult.success("操作成功");
        } catch (Exception e) {
            e.printStackTrace();
            log.error("报错ERROR", e);
            return AjaxResult.fail("操作失败，请稍后再试");
        }
    }

    @Override
    public void excelReader(List<TlOilcostCfg> oilcostCfgList) throws ExcelReaderDataException {

        String uid = LoginUtils.getUser().getUid();
        List<SysDepart> departList = departMapper.selectList(new QueryWrapper<>());
        List<TlCar> carList = carMapper.selectList(new QueryWrapper<>());
        List<CostDictItem> costDictItemList = costDictItemMapper.selectList(new QueryWrapper<>());
        Map<String, TlCar> carMap = new HashMap<>();
        if (!carList.isEmpty()) {
            carMap = carList.stream().collect(Collectors.groupingBy(TlCar::getCarnumber, Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0))));
        }
        Map<String, CostDictItem> costDictItemMap = new HashMap<>();
        if (!costDictItemList.isEmpty()) {
            Predicate<CostDictItem> nameNotNull = costDictItem -> StringUtils.isNotEmpty(costDictItem.getCostname());
            costDictItemList = costDictItemList.stream().filter(nameNotNull).collect(Collectors.toList());
            costDictItemMap = GroupingByUtils.getGroupingForMapEntity(costDictItemList, CostDictItem::getCostname, Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0)));
        }
        Map<String, SysDepart> departMap = new HashMap<>();
        if (!departList.isEmpty()) {
            Predicate<SysDepart> departNameNotNull = depart -> StringUtils.isNotEmpty(depart.getDepartName());
            departList = departList.stream().filter(departNameNotNull).collect(Collectors.toList());
            departMap = GroupingByUtils.getGroupingForMapEntity(departList, SysDepart::getDepartName, Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0)));
        }
        Map<String, User> userMap = new HashMap<>();
        List<User> userList = userMapper.selectList(new QueryWrapper<>());
        userMap = GroupingByUtils.getGroupingForMapEntity(userList, User::getName, Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0)));
        int num = 1;
        String str = "";
        for (TlOilcostCfg oilcostCfg : oilcostCfgList) {
            oilcostCfg.setCreattime(new Date());
            oilcostCfg.setCreatby(uid);
            if (StringUtils.isNotEmpty(oilcostCfg.getCarCardNum())) {
                if (carMap.containsKey(oilcostCfg.getCarCardNum())) {
                    oilcostCfg.setCarnumid(carMap.get(oilcostCfg.getCarCardNum()).getId());
                } else {
                    str += "第" + num + "条的" + "“‘" + "车牌号’:‘" + oilcostCfg.getCarCardNum() + "’”" + "不存在;##";
                }
            } else {
                str += "第" + num + "条的“车牌号”不能为空;##";
            }
            if (departMap.containsKey(oilcostCfg.getDeptName())) {
                oilcostCfg.setDeptid(departMap.get(oilcostCfg.getDeptName()).getId());
                oilcostCfg.setDeptidforcar(departMap.get(oilcostCfg.getDeptName()).getId());
            } else {
                str += "第" + num + "条的" + "“‘" + "所属机构’:‘" + oilcostCfg.getDeptName() + "’”" + "不存在;##";
            }
//            if (costDictItemMap.containsKey(oilcostCfg.getRepairreasonName())) {
//                oilcostCfg.setRepairreason(costDictItemMap.get(oilcostCfg.getRepairreasonName()).getId());
//            } else {
//                str += "第" + num + "条的" + "“‘" + "燃油类型’:‘" + oilcostCfg.getRepairreasonName() + "’”" + "不存在;##";
//            }
            if (Objects.isNull(oilcostCfg.getTotalcost())) {
                str += "第" + num + "条的“总费用”不能为空;##";
            }
            if (Objects.isNull(oilcostCfg.getCosttime())) {
                str += "第" + num + "条的’加油时间‘时间格式不正确;##";
            }
            if (!userMap.containsKey(oilcostCfg.getPayusername())) {
                str += "第" + num + "条的" + "“‘" + "缴费人’:‘" + oilcostCfg.getPayusername() + "’”" + "不存在;##";
            }
            num++;
        }
        if (StringUtils.isNotEmpty(str)) {
            throw new ExcelReaderDataException("您导入的数据:##" + str);
        }
    }

    @Override
    public TlOilcostCfg getitemByid(String id) throws HssException {
        QueryWrapper<TlOilcostCfg> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TlOilcostCfg::getId, id);
        TlOilcostCfg tlOilcostCfg = TlOilcostCfgMapper.selectOne(queryWrapper);
        TlCar car = null;
        TlCarType carType = null;
        SysDepart depart = null;
        User user = null;
        if (tlOilcostCfg != null) {
            car = carService.getById(tlOilcostCfg.getCarnumid());
            depart = departService.getById(tlOilcostCfg.getDeptid());

        }
        if (car != null) {
            carType = carTypeService.getById(car.getCartypeid());
            user = userService.getById(car.getDriverid());
            tlOilcostCfg.setCarCardNum(car.getCarnumber());
        }
        if (carType != null) {
            tlOilcostCfg.setCarTyeName(carType.getTypename());
        }
        if (depart != null) {
            tlOilcostCfg.setDeptName(depart.getDepartName());
        }
        if (user != null) {
            tlOilcostCfg.setDriverName(user.getName());
        }
        return tlOilcostCfg;
    }

    @Override
    @DataScope(deptAlias = "deptidforcar", userAlias = "creatBy")
    public JSONObject listOilCost(BaseEntity entity, JSONObject params) throws HssException {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Long page = StringUtils.isEmpty(params.getLong("page")) ? 1 : params.getLong("page");
        Long size = StringUtils.isEmpty(params.getLong("size")) ? 10 : params.getLong("size");
        JSONObject json = new JSONObject();

        Map map = new HashMap();
        map.put("deptidforcar", params.getString("deptidforcar"));
        map.put("carNumid", params.getString("carNumid"));
        map.put("serviceVendorName", params.getString("serviceVendorName"));
        map.put("oilCardNum", params.getString("oilCardNum"));
        map.put("startTime", AttributeUtils.timeCompletion(params.getString("startTime"), 's'));
        map.put("endTime", AttributeUtils.timeCompletion(params.getString("endTime"), 'e'));
        Page<TlOilcostCfg> oilPage = new Page<>(page, size, true);
        map.put("entity", entity);
        IPage<TlOilcostCfg> iPage = TlOilcostCfgMapper.listOilCost(oilPage, map);
        List<TlOilcostCfg> list = iPage.getRecords();
        Map<String, User> userMap = userService.getUserMap();
        Map<String, TlCar> carMap = carService.getCarMap(new QueryWrapper<>());
        Map<String, SysDepart> departMap = departService.getDepartMap(new QueryWrapper<>());
        Map<String, TlCarType> carTypeMap = carTypeService.getCarTypeMap(new QueryWrapper<>());
//        Map<String, CostDictItem> costDictItemMap = costDictItemService.getCostDictItemMap(new QueryWrapper<>());
        for (TlOilcostCfg tlOilcostCfg : list) {
            if (carMap != null && carMap.containsKey(tlOilcostCfg.getCarnumid())) {
                tlOilcostCfg.setCarCardNum(carMap.get(tlOilcostCfg.getCarnumid()).getCarnumber());
            }
            if (userMap != null && userMap.containsKey(tlOilcostCfg.getDrivernameid())) {
                tlOilcostCfg.setDriverName(userMap.get(tlOilcostCfg.getDrivernameid()).getName());
            }
            if (carTypeMap != null && carTypeMap.containsKey(tlOilcostCfg.getCartype())) {
                tlOilcostCfg.setCarTyeName(carTypeMap.get(tlOilcostCfg.getCartype()).getTypename());
            }
            if (departMap != null && departMap.containsKey(tlOilcostCfg.getDeptid())) {
                tlOilcostCfg.setDeptName(departMap.get(tlOilcostCfg.getDeptid()).getDepartName());
            }
            if (Objects.nonNull(tlOilcostCfg.getCosttime())) {
                tlOilcostCfg.setCosttimeString(format.format(tlOilcostCfg.getCosttime()));
            }
//            if (costDictItemMap.containsKey(tlOilcostCfg.getRepairreason())) {
//                tlOilcostCfg.setRepairreasonName(costDictItemMap.get(tlOilcostCfg.getRepairreason()).getCostname());
//            }

        }
        json.put("total", iPage.getTotal());
        json.put("size", iPage.getSize());
        json.put("pages", iPage.getPages());
        json.put("current", iPage.getCurrent());
        json.put("oillist", iPage.getRecords());
        return json;
    }

    @Override
    @DataScope(deptAlias = "deptidforcar", userAlias = "creatBy")
    public List<TlOilcostCfg> getTlOilcostCfgList(TlOilcostCfgListTO oilcostCfgListTO, SimpleDateFormat format) throws ParseException {
        QueryWrapper<TlOilcostCfg> inspectionCfgQueryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(oilcostCfgListTO.getDeptid())) {
            inspectionCfgQueryWrapper.lambda().eq(TlOilcostCfg::getDeptid, oilcostCfgListTO.getDeptid());
        }
        if (StringUtils.isNotEmpty(oilcostCfgListTO.getCarNumid())) {
            inspectionCfgQueryWrapper.lambda().eq(TlOilcostCfg::getCarnumid, oilcostCfgListTO.getCarNumid());
        }
        if (oilcostCfgListTO.getParams().containsKey("dataScope") && StringUtils.isNotEmpty(oilcostCfgListTO.getParams().get("dataScope").toString())) {
            inspectionCfgQueryWrapper.lambda().apply(oilcostCfgListTO.getParams().get("dataScope").toString());
        }
        if (StringUtils.isNotEmpty(oilcostCfgListTO.getOilCardNum())) {
            inspectionCfgQueryWrapper.lambda().eq(TlOilcostCfg::getOilcardnum, oilcostCfgListTO.getOilCardNum());
        }
        if (oilcostCfgListTO.getIds() != null && !oilcostCfgListTO.getIds().isEmpty()) {
            inspectionCfgQueryWrapper.lambda().in(TlOilcostCfg::getId, oilcostCfgListTO.getIds());
        }
        if (StringUtils.isNotEmpty(oilcostCfgListTO.getStartTime()) && StringUtils.isNotEmpty(oilcostCfgListTO.getEndTime())) {
            inspectionCfgQueryWrapper.lambda().ge(TlOilcostCfg::getCosttime, format.parse(oilcostCfgListTO.getStartTime()));
            inspectionCfgQueryWrapper.lambda().le(TlOilcostCfg::getCosttime, format.parse(oilcostCfgListTO.getEndTime()));
        }
        List<TlOilcostCfg> oilcostCfgList = TlOilcostCfgMapper.selectList(inspectionCfgQueryWrapper);
        return oilcostCfgList;
    }

    @Override
    public JSONObject getDcylqxJysjList(JSONObject params) throws HssException {
        Long page = StringUtils.isEmpty(params.getLong("page")) ? 1 : params.getLong("page");
        Long size = StringUtils.isEmpty(params.getLong("size")) ? 10 : params.getLong("size");
        JSONObject json = new JSONObject();

        Map map = new HashMap();
        map.put("carNumid", params.getString("carNumid"));
        map.put("startDate", params.getString("startDate"));
        map.put("endDate", params.getString("endDate"));
        Page<TlOilcostCfgRes> oilPage = new Page<>(page, size, true);
        IPage<TlOilcostCfgRes> iPage = TlOilcostCfgMapper.getDcylqxJysjList(oilPage, map);
        json.put("total", iPage.getTotal());
        json.put("size", iPage.getSize());
        json.put("pages", iPage.getPages());
        json.put("current", iPage.getCurrent());
        json.put("oillist", iPage.getRecords());
        return json;
    }
}
